package com.study.springsecurity.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.study.springsecurity.entity.Menu;
import com.study.springsecurity.entity.MyUserDetails;
import com.study.springsecurity.entity.Role;
import com.study.springsecurity.entity.UserInfo;
import com.study.springsecurity.mapper.UsersMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Slf4j
@Primary
@Service
public class DBUserDetailsService implements UserDetailsService {

    @Autowired
    private UsersMapper usersMapper;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        QueryWrapper<UserInfo> wrapper = new QueryWrapper();
        wrapper.eq("username", username);
        UserInfo userInfo = usersMapper.selectOne(wrapper);
        if (userInfo == null) {
            throw new UsernameNotFoundException("用户名不存在！");
        }

        // 获取用户角色、菜单列表
        List<Role> roles = usersMapper.selectRoleByUserId(userInfo.getId());
        List<Menu> menus = usersMapper.selectMenuByUserId(userInfo.getId());

        log.info("selectOne username={},userInfo={},roles={},menus={}", username, userInfo, roles, menus);

        List<GrantedAuthority> grantedAuthorityList = new ArrayList<>(); // 声明一个集合List<GrantedAuthority>
        // List<GrantedAuthority> grantedAuthorityList = AuthorityUtils.commaSeparatedStringToAuthorityList("role1,role2");
        // List<GrantedAuthority> grantedAuthorityList = AuthorityUtils.createAuthorityList(menus.toArray(new String[0]));

        // 处理角色
        for (Role role : roles) {
            // 角色之所以要使用ROLE_开头，是为了和ExpressionUrlAuthorizationConfigurer.AuthorizedUrl.hasRole(String role)方法一致
            grantedAuthorityList.add(new SimpleGrantedAuthority("ROLE_" + role.getName()));
        }

        // 处理权限
        for (Menu menu : menus) {
            // 和ExpressionUrlAuthorizationConfigurer.AuthorizedUrl.hasAuthority(String authority)相对应
            grantedAuthorityList.add(new SimpleGrantedAuthority(menu.getPermission()));
        }
        return new MyUserDetails(userInfo.getId(), userInfo.getUsername(), userInfo.getPassword(), grantedAuthorityList);
    }
}
